﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

using HMEngine.HMCameras;
using HMEngine.HMEffects;
using HMEngine.HMComponents;

namespace HMEngine.HMObjects {
    public class HMSkybox : HMObject, IHMRenderable, IHMLoadable {
        private readonly HMQuad[] mySides;
        private readonly string[] myFiles;
        private readonly Color myColor;
        private readonly Vector3[] myOffsets;

        public string Shader { get; set; }
        public VertexDeclaration VertexDeclaration { get { return mySides[0].VertexDeclaration; } }

        public HMSkybox(string[] textures, Color color) {
            myFiles = textures;
            mySides = new HMQuad[6];
            myOffsets = new Vector3[6];
            myColor = color;

            CreateSides();
        }

        private void CreateSides() {
            for (int i = 0; i < 6; i++) {
                mySides[i] = new HMQuad(myFiles[i], myColor) {Scaling = new Vector3(5)};
            }

            mySides[0].Rotation = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), MathHelper.PiOver2);
            mySides[1].Rotation = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), -MathHelper.PiOver2);
            mySides[2].Rotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), MathHelper.PiOver2);
            mySides[3].Rotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), -MathHelper.PiOver2);
            mySides[5].Rotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), MathHelper.Pi);

            CalculateOffsets();
        }

        private void CalculateOffsets() {
            myOffsets[0] = new Vector3(0, 0.5f, 0) * new Vector3(5);
            myOffsets[1] = new Vector3(0, -0.5f, 0) * new Vector3(5);
            myOffsets[2] = new Vector3(-0.5f, 0, 0) * new Vector3(5);
            myOffsets[3] = new Vector3(0.5f, 0, 0) * new Vector3(5);
            myOffsets[4] = new Vector3(0, 0, -0.5f) * new Vector3(5);
            myOffsets[5] = new Vector3(0, 0, 0.5f) * new Vector3(5);
        }

        public void LoadContent(GraphicsDevice myDevice, ContentManager myLoader) {
            foreach (HMQuad quad in mySides) {
                quad.LoadContent(myDevice, myLoader);
            }
        }

        public void Render(GraphicsDevice myDevice) {
            myDevice.RenderState.DepthBufferWriteEnable = false;
            for (int i = 0; i < 6; i++) {
                mySides[i].Position = HMCameraManager.ActiveCamera.Position + myOffsets[i];
                HMEffectManager.ActiveShader.SetParameters(mySides[i]);
                mySides[i].Render(myDevice);
            }
            myDevice.RenderState.DepthBufferWriteEnable = true;
        }
    }
}